package com.ybear.ybutilapp;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Message;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.arch.core.util.Function;
import androidx.core.util.Consumer;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;

import com.ybear.ybcomponent.base.adapter.IItemData;
import com.ybear.ybcomponent.widget.ItemSwipeLayout;
import com.ybear.ybcomponent.widget.MaskImageView;
import com.ybear.ybcomponent.widget.ToolbarView;
import com.ybear.ybcomponent.widget.dialog.Dialog;
import com.ybear.ybcomponent.widget.dialog.DialogLifecycleAdapter;
import com.ybear.ybcomponent.widget.dialog.DialogOption;
import com.ybear.ybcomponent.widget.dialog.DialogPermission;
import com.ybear.ybcomponent.widget.dialog.DialogQueue;
import com.ybear.ybnetworkutil.call.CallReqAdapter;
import com.ybear.ybnetworkutil.http.HttpClient;
import com.ybear.ybnetworkutil.network.NetworkChangeManage;
import com.ybear.ybutils.utils.AnimationPool;
import com.ybear.ybutils.utils.BackgroundPopupUiManager;
import com.ybear.ybutils.utils.IOUtil;
import com.ybear.ybutils.utils.LiveTime;
import com.ybear.ybutils.utils.LocaleUtil;
import com.ybear.ybutils.utils.ObjUtils;
import com.ybear.ybutils.utils.StackManage;
import com.ybear.ybutils.utils.SysUtil;
import com.ybear.ybutils.utils.UUIDUtils;
import com.ybear.ybutils.utils.Utils;
import com.ybear.ybutils.utils.design.AbsLogger;
import com.ybear.ybutils.utils.design.ResponsibilityManage;
import com.ybear.ybutils.utils.handler.CallbackAdapter;
import com.ybear.ybutils.utils.handler.Handler;
import com.ybear.ybutils.utils.handler.HandlerManage;
import com.ybear.ybutils.utils.handler.ThreadPool;
import com.ybear.ybutils.utils.log.LogUtil;
import com.ybear.ybutils.utils.notification.NotificationX;
import com.ybear.ybutils.utils.time.DateTime;
import com.ybear.ybutils.utils.toast.ToastManage;
import com.ybear.ybutils.utils.toast.ToastX;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import okhttp3.Call;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SysUtil.setTheme( this, R.style.defaultActivity );

        LiveTime liveTime = LiveTime.get();
        //启动全部id
        liveTime.startLiveTime();
        //或者
        //启动指定id
//        liveTime.startLiveTime(
//                HandlerManage.create(),
//                TestApplication.LIVE_TIME_ID_TEXT_1_SECOND,
//                TestApplication.LIVE_TIME_ID_TEXT_5_SECOND
//        );

        findViewById( R.id.btn_send_notice ).setOnClickListener(v -> {
            /* 展示一条通知 */
            if( NotificationX.get().areNotificationsEnabled( this ) ) {
                Intent intent = new Intent( this, TestActivity.class );
                boolean notifyResult = NotificationX.get()
                        .showNotification(
                                this, 533245, "测试标题", "测试内容233",
                                intent, true
                        );
                ToastManage.get().showToast( this, "展示通知结果：" + notifyResult );
            }else {
                //申请通知栏权限
                boolean reqResult = NotificationX.get().requestNotification( this );
                ToastManage.get().showToast( this, "申请通知栏权限结果：" + reqResult );
            }
        });

        findViewById( R.id.btn_system_dialog ).setOnClickListener(v -> {
            //发起系统级对话框权限申请
            DialogPermission.get().applyOverlayPermission(this, result -> {
                if( !result ) {
                    ToastManage.get().showToast( this, "无权限" );
                    return;
                }
                FragmentActivity activity = MainActivity.this;
                Dialog.with( activity )
                        .title("测试普通Dialog")
                        .message("普通Dialog")
                        .onPositiveButtonListener("关闭", (dialog, which) -> {
                            dialog.dismiss();
//                    ToastManage.get().showToast( this, "正在跳转..." );
//                    startActivity( new Intent( this, TestActivity.class ) );
                        }).onNegativeButtonListener("恢复DialogQueue", (dialog, which) -> {
                            dialog.dismiss();
                            ToastManage.get().showToast( activity, "已恢复Queue" );
                            //恢复
                            DialogQueue.get().resumeQueue();
                        })
                        //系统级对话框
                        .systemDialog( activity, true )
                        .create()
                        .cancelable( false )
                        .canceledOnTouchOutside( false )
                        //透传事件
                        .getTouchEvent().setOnTransferTouchEvent( activity )
                        .show();
            });
        });

        findViewById( R.id.btn_full_screen ).setOnClickListener(v -> {
            boolean isEnable = ObjUtils.parseInt( v.getTag() ) == 0;
            v.setTag( isEnable ? 1 : 0 );
            SysUtil.setFullScreen( getWindow(), isEnable );
            ( ( TextView)v ).setText( isEnable ? "退出全屏" : "开启全屏" );
        });

        findViewById( R.id.btn_immersive ).setOnClickListener(v -> {
            boolean isEnable = ObjUtils.parseInt( v.getTag() ) == 0;
            v.setTag( isEnable ? 1 : 0 );
            SysUtil.immersiveStatusBar( getWindow(), isEnable );
            ( ( TextView)v ).setText( isEnable ? "退出沉浸式" : "开启沉浸式" );
        });

        findViewById( R.id.btn_test_activity ).setOnClickListener(v -> {
            startActivity( new Intent( this, TestActivity.class ) );
        });

        ToastX mToast = ToastManage.get().makeText( this );
        mToast.setText( "DEBUG: " + LogUtil.isDebug() ).show();

        /* 时间转换 */
        LogUtil.e("Time -> " +
                DateTime.parse( 1592474989 ) + " | " +
                DateTime.parse( DateTime.currentTimeMillis() ) + " | " +
                DateTime.parseOfList( DateTime.currentTimeMillis() ) + " | " +
                DateTime.now() + " | " +
                DateTime.nowOfList()
        );
        //暂停队列
        DialogQueue.get().pauseQueue();

        new TestDialogOption( this ).showByQueue();

        Dialog.with( this )
                .title("测试队列Dialog - 1")
                .message("队列Dialog")
                .onPositiveButtonListener("打开TestActivity", (dialog, which) -> {
                    dialog.dismiss();
                    ToastManage.get().showToast( this, "正在跳转..." );
                    startActivity( new Intent( this, TestActivity.class ) );

                }).onNegativeButtonListener("关闭", (dialog, which) -> {
                    dialog.dismiss();
                }).create().showByQueue();

        MaskImageView miv = findViewById( R.id.miv );
        miv.setImageResource( R.mipmap.ic_launcher, 100, 100 );
        miv.setForegroundMask( R.mipmap.ic_launcher );
        miv.setBackgroundMask( R.mipmap.ic_launcher );
        miv.setBackgroundColor( Color.BLACK );
        miv.setStartOfProgress( 0 );
        miv.setDuration( 1000 );

        CountDownTimer cdt = new CountDownTimer( 10000, 1000 ){
            @Override
            public void onTick(long millisUntilFinished) {
                miv.post( () -> miv.startAnimOfProgress( 0, 100 ) );
                LogUtil.d( "TAG", "MaskImageView -> " + millisUntilFinished );
            }

            @Override
            public void onFinish() { }
        };
        cdt.start();


        ToolbarView tbv = findViewById(R.id.toolbar);
        tbv.setOtherBtnOfImg(R.drawable.ic_toolbar_back);
        tbv.showOtherBtnOfImg( true );

        /* 动画池 */
        AnimationPool animPool = AnimationPool.get();
        AnimationPool.AnimationHolder holder = new AnimationPool.AnimationHolder(
                ObjUtils.parseObject( R.mipmap.ic_launcher ), new OnFlyOnAnimBuild()
        );
        holder.setXInterpolator( new AccelerateInterpolator() );
//        holder.setYInterpolator( new DecelerateInterpolator() );
        holder.setXDuration( 10000 );
        holder.setYDuration( 8000 );
        holder.setFromView( miv );
        //是否隐藏FromView
        holder.setHideFromView( true );
        //隐藏FromView的可见性
        holder.setHideFromViewVisibility( View.INVISIBLE );
        //第一种写法
//        holder.setToView( tbv );
        //第二种写法（FromView同理）
        holder.setToView(
                SysUtil.getScreenWidth( this ) - animPool.getCenterAlignOfWidth( tbv.getLayoutParams() ),
                SysUtil.getScreenHeight( this ) - animPool.getCenterAlignOfHeight( tbv.getLayoutParams() )
        );
        AnimationPool.CreateQueue animationQueue = animPool.with( getWindow() );
        animationQueue.addAnimationHolder( holder );

        AnimationPool.AnimationBuilder builder = animationQueue.createQueue();
        //同时播放
//        builder.startQueueSync();
        //队列播放
        builder.startQueue();

        HandlerManage.create().postDelayed(() -> {
            builder.pauseQueue();
            //同时播放
//            HandlerManage.create().postDelayed(builder::startQueueSync, 3000);
            //队列播放
            HandlerManage.create().postDelayed(builder::startQueue, 3000);
        }, 3000);

        ItemSwipeLayout isLayout = findViewById(R.id.main_isl_item_swipe);
        isLayout.setEnableSwipeDrag( true );
        View[] views = new View[ 3 ];
        int[] colors = { R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark };
        for (int i = 0; i < views.length; i++) {
            TextView tv = new TextView( this );
            tv.setText( new StringBuffer().append( "测试" ).append( i ) );
            tv.setBackgroundResource( colors[i] );
            tv.setGravity(Gravity.CENTER);
            views[ i ] = tv;
        }
        isLayout.setSwipeViews( views );
        isLayout.setEnableMultiSwipeDrag( false );
        isLayout.setOnSwipeItemClickListener((view, childView, position) ->
                LogUtil.e("TAG", position + " " + childView)
        );

        LogUtil.e( "TAG", "测试保存日志时是否会乱码。abcdefgABCDEFG123456!@#$%^&*()_+" );
        isLayout.setOnClickListener(view -> LogUtil.e("TAG", "OnClick:" + view));

//        isLayout.getItemView().setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                LogUtil.e("TAG", view + "");
//            }
//        });

        ViewPager pager = findViewById(R.id.rv_pager);

        HandlerManage.create().postAsync(() -> {
            List<TestRvPagerAdapter.ItemData> pagerList = new ArrayList<>();
            for (int i = 1; i <= 20000; i++) {
                pagerList.add(new TestRvPagerAdapter.ItemData().setTitle("【测试高亮】测试页面 " + i + "测试高亮, 限制2次测试高亮"));
            }
            return pagerList;
        }, pagerList -> {
            TestRvPagerAdapter pagerAdapter = new TestRvPagerAdapter(pagerList);
            pager.setAdapter(pagerAdapter);
            pager.setOffscreenPageLimit(5);
            pager.setCurrentItem(19999);
        });

        HttpClient.create().build().addReqDataListener(new CallReqAdapter() {
            @Override
            public void onResponse(@NonNull Call call, @NonNull Response r) throws IOException {
                super.onResponse(call, r);
                LogUtil.d("TAG", "r: " + r);
            }

            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                super.onFailure(call, e);
                LogUtil.d("TAG", "f: " + e.getMessage());
            }
        } ).req("https://haokan.baidu.com/v?vid=17417821379914441855&tab=").get();

        IOUtil.saveFile(
                getExternalFilesDir( null ).getAbsolutePath(),
                "aaa.txt", "111".getBytes(),
                it -> {
                    LogUtil.e("TAG", "111 -> " + it );
                    return null;
                }
        );


        Handler handler = HandlerManage.create(new CallbackAdapter<String>("Test string data") {
            @Override
            public boolean handleMessage(@NonNull Message msg, @Nullable String data) {
                LogUtil.e("Handler -> handleMessage:" + msg.what + " | data:" + data);
                return true;
            }

            @Override
            public void dispatchMessage(@NonNull Message msg, @Nullable String data) {
                LogUtil.e("Handler -> dispatchMessage:" + msg.what + " | data:" + data);
            }
        });

        //打开ShatsApp
//        StartUtils.startWhatsApp( this, "12345678" );

        IOUtil.saveFile(
                getExternalFilesDir(null).getAbsolutePath(),
                "aaa.txt",
                "222".getBytes(),
                true,
                it -> {
                    handler.post( () -> LogUtil.e( "TAG", "222 -> " + it ), 1000 );
                    return null;
                });


//        handler.sendEmptyMessage( 111 );
        handler.sendEmptyMessageAtTime( 2222, 10000 );
        handler.sendEmptyMessageDelayed( 3333, 3000 );

        Message msg = handler.obtainMessage();
        msg.what = 4444;
        handler.sendMessageDelayed( msg, 5000 );

        //改变当前语言环境
        LocaleUtil.changeAppLanguage( this, Locale.ENGLISH.getLanguage() );
        //当前语言。eg: zh, en, ko, jp...
        String curLanguage = LocaleUtil.getLanguage();
        //当前语言（携带国家）。eg: zh-CN, zh-TW
        String curLanguageAndCountry = LocaleUtil.getLanguage( true );
        //是否为ltr布局
        boolean isLtr = LocaleUtil.isLtrLayout();
        //是否为rtl布局
        boolean isRtl = LocaleUtil.isRtlLayout();
        LogUtil.d(
                "TAG_LocaleUtil",
                "curLanguage:%s, curLanguageAndCountry:%s, isLtr:%s, isRtl:%s",
                curLanguage, curLanguageAndCountry, isLtr, isRtl
        );

//        LeadTime leadTime = new LeadTime();
//        for (long i = 0; i < 315_3600_0000L; i++) {
//            long ts = System.currentTimeMillis() + i * 100000;
//            DateTime.toLeadTime( ts, System.currentTimeMillis(), leadTime );
//            LogUtil.e( "TAG_DateTime",
//                    DateTime.parse(ts) + " | " + leadTime
//            );
//        }

        HandlerManage.create().postAsync(() -> {
            for (PackageInfo pi : SysUtil.getInstalledPackages( MainActivity.this )) {
                int labelRes = pi.applicationInfo.labelRes;
                String name = null;
                try {
                    if( labelRes > 0 ) name = getResources().getString( labelRes );
                    LogUtil.d( "MainActivityTAG", "Name:%s ---> pkgName:%s",
                            name == null ? labelRes : name,
                            pi.packageName
                    );
                } catch (Resources.NotFoundException e) {
                    LogUtil.e( "MainActivityTAG", "Name:error!, e:%s",
                            e.getMessage()
                    );
                }
            }
        });


        //异步处理数据
        HandlerManage.create().postAsync(() -> {
            LogUtil.d( "HandlerTAG", "postAsync -> call -> running...");
            Thread.sleep( 10000 );
            JSONObject json = new JSONObject();
            json.put( "code", 200 );
            json.put( "msg", "success" );
            LogUtil.d( "HandlerTAG", "postAsync -> call -> json:" + json );
            return json.toString();
        }, strJson -> {
            try {
                JSONObject json = new JSONObject( strJson );
                LogUtil.d(
                        "HandlerTAG",
                        "postAsync -> accept -> code:%s, msg:%s",
                        json.getInt( "code" ), json.getString( "msg" )
                );
            } catch (JSONException e) {
                e.printStackTrace();
                LogUtil.d( "HandlerTAG", "postAsync -> accept -> error");
            }
        });

        HandlerManage.create().postAsync(() -> {
            LogUtil.e( "TAG", "Memory -> " +
                            "avail:%s, availDouble:%s, availCeil:%s, total:%s, totalDouble:%s, totalCeil:%s",
                    SysUtil.getAvailMemory( this ),
                    SysUtil.getAvailMemoryOfDouble( this ),
                    SysUtil.getAvailMemoryOfCeil( this ),
                    SysUtil.getTotalMemory( this ),
                    SysUtil.getTotalMemoryOfDouble( this ),
                    SysUtil.getTotalMemoryOfCeil( this )
            );
            LogUtil.e( "TAG", "NumSize -> " +
                            "\n1399:%s, 100.01:%s, 100.02:%s, 100.03:%s" +
                            "\n100.04:%s, 1050:%s, 1060:%s, 1070:%s" +
                            "\n1080:%s, 1090:%s, 123456789.23:%s",
                    ObjUtils.toNumberSize( this, Locale.US, 1399, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 100.01, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 100.02, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 100.03, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 100.04, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 1050, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 1060.06, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 1070.07, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 1080.08, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 1090.09, 2, true ),
                    ObjUtils.toNumberSize( this, Locale.US, 123456789.23, 2, true )

            );
        });

         Dialog.with( this )
                 .transparentBackground()
                .defaultDimAmount()
                .animOfBottomTranslate()
                .cornerRadiusTop( Utils.dp2Px( this, 20 ) )
                .dialogLifecycle(new DialogLifecycleAdapter() {
                    @Override
                    public void onViewCreate(
                            @NonNull DialogOption option, @Nullable Bundle savedInstanceState
                    ) {
                        super.onViewCreate(option, savedInstanceState);
                        TextView tv2 = option.findViewById( R.id.tv_content );
                        if( tv2 != null ) tv2.setText( "底部弹窗[MATCH]" );
                        RecyclerView rv2 = option.findViewById( R.id.rv_list );
                        if( rv2 != null ) recyclerViewOfScrollStuck( rv2 );
                        Button btnChanged2 = option.findViewById( R.id.btn_changed_height );
                        if( btnChanged2 != null ) {
                            btnChanged2.setOnClickListener( v ->
                                    option.updateDialogHeight(
                                            Utils.dp2Px( option.getContext(), 200 )
                                    )
                            );
                        }
                        Button btnReset2 = option.findViewById( R.id.btn_reset_size );
                        if( btnReset2 != null ) {
                            btnReset2.setOnClickListener( v -> option.resetDialogSize() );
                        }
                    }
                }).createOfMatch( R.layout.dialog_test_last )
                 .showByQueue();

        Dialog.with( this )
                .transparentBackground()
                .defaultDimAmount()
                .animOfBottomTranslate()
                .cornerRadiusTop( Utils.dp2Px( this, 12 ) )
                .dialogLifecycle(new DialogLifecycleAdapter() {
                    @Override
                    public void onViewCreate(
                            @NonNull DialogOption option, @Nullable Bundle savedInstanceState
                    ) {
                        super.onViewCreate(option, savedInstanceState);
                        TextView tv3 = option.findViewById( R.id.tv_content );
                        if( tv3 != null ) tv3.setText( "底部弹窗[MATCH_AND_FREE]" );
                        RecyclerView rv3 = option.findViewById( R.id.rv_list );
                        if( rv3 != null ) recyclerViewOfScrollStuck( rv3 );
                        Button btnChanged3 = option.findViewById( R.id.btn_changed_height );
                        if( btnChanged3 != null ) {
                            btnChanged3.setOnClickListener( v ->
                                    option.updateDialogHeight(
                                            Utils.dp2Px( option.getContext(), 200 )
                                    )
                            );
                        }
                        Button btnReset3 = option.findViewById( R.id.btn_reset_size );
                        if( btnReset3 != null ) {
                            btnReset3.setOnClickListener( v -> option.resetDialogSize() );
                        }
                    }
                }).createOfMatchAndFree( R.layout.dialog_test_last )
                .showByQueue();

        Dialog.with( this )
                .transparentBackground()
                .defaultDimAmount()
                .animOfCenterAlpha()
                .cornerRadius( Utils.dp2Px( this, 20 ) )
                .dialogLifecycle(new DialogLifecycleAdapter() {
                    @Override
                    public void onViewCreate(
                            @NonNull DialogOption option, @Nullable Bundle savedInstanceState
                    ) {
                        super.onViewCreate(option, savedInstanceState);
                        TextView tv4 = option.findViewById( R.id.tv_content );
                        if( tv4 != null ) tv4.setText( "居中弹窗[w:300, h:300]" );
                        RecyclerView rv4 = option.findViewById( R.id.rv_list );
                        if( rv4 != null ) recyclerViewOfScrollStuck( rv4 );
                        Button btnChanged4 = option.findViewById( R.id.btn_changed_height );
                        if( btnChanged4 != null ) {
                            btnChanged4.setOnClickListener( v ->
                                    option.updateDialogHeight(
                                            Utils.dp2Px( option.getContext(), 200 )
                                    )
                            );
                        }
                        Button btnReset4 = option.findViewById( R.id.btn_reset_size );
                        if( btnReset4 != null ) {
                            btnReset4.setOnClickListener( v -> option.resetDialogSize() );
                        }
                    }
                }).createOfFree(
                        R.layout.dialog_test_last,
                        Utils.dp2Px( this, 300 ),
                        Utils.dp2Px( this, 300 )
                ).showByQueue();

        Dialog.with( this )
                .defaultDimAmount()
                .transparentBackground()
                .animOfBottomTranslate()
                .cornerRadiusTop( Utils.dp2Px( this, 12 ) )
                .dialogLifecycle(new DialogLifecycleAdapter() {
                    @Override
                    public void onViewCreate(
                            @NonNull DialogOption option, @Nullable Bundle savedInstanceState
                    ) {
                        super.onViewCreate(option, savedInstanceState);
                        TextView tv5 = option.findViewById( R.id.tv_content );
                        if( tv5 != null ) tv5.setText( "底部弹窗[w:MATCH_PARENT, h:500]" );
                        RecyclerView rv5 = option.findViewById( R.id.rv_list );
                        if( rv5 != null ) recyclerViewOfScrollStuck( rv5 );
                        Button btnChanged5 = option.findViewById( R.id.btn_changed_height );
                        if( btnChanged5 != null ) {
                            btnChanged5.setOnClickListener( v ->
                                    option.updateDialogHeight(
                                            Utils.dp2Px( option.getContext(), 200 )
                                    )
                            );
                        }
                        Button btnReset5 = option.findViewById( R.id.btn_reset_size );
                        if( btnReset5 != null ) {
                            btnReset5.setOnClickListener( v -> option.resetDialogSize() );
                        }
                    }
                }).createOfFree(
                        R.layout.dialog_test_last,
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        Utils.dp2Px( this, 500 )
                ).showByQueue();

        Dialog.with( this )
                .transparentBackground()
                .defaultDimAmount()
                .animOfCenterBottomTranslate()
                .cornerRadiusTop( Utils.dp2Px( this, 60 ) )
                .measure()
                .dialogLifecycle(new DialogLifecycleAdapter() {
                    @Override
                    public void onViewCreate(
                            @NonNull DialogOption option, @Nullable Bundle savedInstanceState
                    ) {
                        super.onViewCreate(option, savedInstanceState);
                        TextView tv6 = option.findViewById( R.id.tv_content );
                        if( tv6 != null ) tv6.setText( "底部到居中弹窗[自由]" );
                        RecyclerView rv6 = option.findViewById( R.id.rv_list );
                        if( rv6 != null ) recyclerViewOfScrollStuck( rv6 );
                        Button btnChanged6 = option.findViewById( R.id.btn_changed_height );
                        if( btnChanged6 != null ) {
                            btnChanged6.setOnClickListener( v ->
                                    option.updateDialogHeight(
                                            Utils.dp2Px( option.getContext(), 200 )
                                    )
                            );
                        }
                        Button btnReset6 = option.findViewById( R.id.btn_reset_size );
                        if( btnReset6 != null ) {
                            btnReset6.setOnClickListener( v -> option.resetDialogSize() );
                        }
                    }
                }).createOfFree( R.layout.dialog_test_last )
                .showByQueue();

        Dialog.with( this )
                .transparentBackground()
                .defaultDimAmount()
                .animOfBottomTranslate()
                .cornerRadiusTop( Utils.dp2Px( this, 60 ) )
                .dialogLifecycle(new DialogLifecycleAdapter() {
                    @Override
                    public void onViewCreate(
                            @NonNull DialogOption option, @Nullable Bundle savedInstanceState
                    ) {
                        super.onViewCreate(option, savedInstanceState);
                        TextView tv7 = option.findViewById( R.id.tv_content );
                        if( tv7 != null ) tv7.setText( "底部弹窗[自由+测量]" );
                        RecyclerView rv7 = option.findViewById( R.id.rv_list );
                        if( rv7 != null ) recyclerViewOfScrollStuck( rv7 );
                        Button btnChanged7 = option.findViewById( R.id.btn_changed_height );
                        if( btnChanged7 != null ) {
                            btnChanged7.setOnClickListener( v ->
                                    option.updateDialogHeight(
                                            Utils.dp2Px( option.getContext(), 200 )
                                    )
                            );
                        }
                        Button btnReset7 = option.findViewById( R.id.btn_reset_size );
                        if( btnReset7 != null ) {
                            btnReset7.setOnClickListener( v -> option.resetDialogSize() );
                        }
                    }
                }).measure()
                .createOfFree( R.layout.dialog_test_last )
                .showByQueue();

        for (int i = 0; i < 10; i++) {
            int fi = i;
            Dialog.with( this )
                    .title("测试队列Dialog - 10")
                    .message( String.format( "队列Dialog（%s/%s）", i + 1, 10 ) )
                    .onPositiveButtonListener((dialog, which) -> {
                        dialog.dismiss();
                        ToastManage.get().showToast( this, "确定按钮" );
                        startActivity( new Intent( this, TestActivity.class ) );

                    }).onNegativeButtonListener("关闭对话框", (dialog, which) -> {
                        dialog.cancel();
                        ToastManage.get().showToast( this, "关闭了对话框" );
                    })
                    .create()
                    .onDismissListener(dialog ->
                            ToastManage.get().showToast(
                                    this, String.format( "队列Dialog %s OnDismiss", fi + 1 )
                            )
                    ).showByQueue();
        }

        for (int i = 0; i < 5; i++) {
            LogUtil.d( "TAG", String.format( "pool %s:%s", ( i + 1 ), ThreadPool.get() ) );
        }

        LogUtil.d( "TAG", "deviceId:%s, phoneIMEI:%s",
                UUIDUtils.getDeviceId( this ), UUIDUtils.getPhoneIMEI( this )
        );

        //责任链
        HandlerManage.create().postAsync( this::doResponsibilityManage );


//        HandlerManage.create().postAsync(() -> {
//            for (int i = 0; i < 10000; i++) {
//                final String tag = "tag:index_" + i;
//                DOM.getInstance().registerResult((id, data) ->
//                        LogUtil.d( "TAG", "MainActivity.onResult -> tag:%s, id:%s, data:%s",
//                                tag, id, data
//                        )
//                );
//            }
//            for (int i = 0; i < 10; i++) {
//                DOM.getInstance().setResult( 88776333, "index:" + i );
//            }
//        });
    }

    private void recyclerViewOfScrollStuck(RecyclerView rv) {
        LinearLayoutManager llm = new LinearLayoutManager( this );
        rv.setLayoutManager( llm );
        List<IItemData> list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            list.add( null );
        }
        TestScrollStuckRvAdapter mAdapter = new TestScrollStuckRvAdapter( rv );
        mAdapter.addItemData( list );
        rv.setAdapter( mAdapter );
    }

    private void doResponsibilityManage() {
        ResponsibilityManage rm = ResponsibilityManage.Companion.get();

        AbsLogger logger102 = new AbsLogger( 102 ) {
            @Override
            public boolean write() {
                LogUtil.d( "TAG", "ResponsibilityManage -> 102.next.write.id:" + getLoggerId() );
                return false;
            }
        };

        AbsLogger logger101 = new AbsLogger( 101 ) {
            @Override
            public boolean write() {
                LogUtil.d( "TAG", "ResponsibilityManage -> 101.next.write.id:" + getLoggerId() );
                return false;
            }
        };
        logger101.setNextLogger( logger102 );
        logger101.setLoggerEndFinishCall( id ->
                LogUtil.d( "TAG", "ResponsibilityManage -> 101.finishCall.id:" + id )
        );
        rm.addLogger( logger101 );

        AbsLogger logger100 = new AbsLogger( 100 ) {
            @Override
            public boolean write() {
                LogUtil.d( "TAG", "ResponsibilityManage -> 100.cur.write.id:" + getLoggerId() );
                return false;
            }
        };

        logger100.setNextLogger( logger101 );
        logger101.setLoggerEndFinishCall( id ->
                LogUtil.d( "TAG", "ResponsibilityManage -> 100.finishCall.id:" + id )
        );
        rm.addLogger( logger100 );
        rm.runLogger( 100 );

        boolean isAllowedBackgroundPopupUi = BackgroundPopupUiManager
                .getInstance()
                .isAllowedBackgroundPopupUi( this );
        LogUtil.d( "TAG", "isAllowedBackgroundPopupUi: %s", isAllowedBackgroundPopupUi );
    }

    @Override
    protected void onResume() {
        super.onResume();
        NetworkChangeManage ncm = NetworkChangeManage.get();
        if( !ncm.isRunningService() ) ncm.registerService( HandlerManage.create().getOsHandler() );

        LiveTime liveTime = LiveTime.get();
        /* 防止心跳突然停止 */
        //检查全部id
        liveTime.checkLiveTime();
//        //或者
//        liveTime.checkLiveTime(
//                HandlerManage.create(),
//                false,  //是否强制退出
//                TestApplication.LIVE_TIME_ID_TEXT_5_SECOND
//        );
//        //或者
//        liveTime.checkLiveTime(
//                HandlerManage.create(),
//                TestApplication.LIVE_TIME_ID_TEXT_1_SECOND,
//                TestApplication.LIVE_TIME_ID_TEXT_5_SECOND
//        );
    }

    @Override
    protected void onPause() {
        super.onPause();
        //除了MainActivity之外，没有其他页面时，解除注册服务
        if( !StackManage.get().isHaveExistActivityOfSkip( "MainActivity" ) ) {
            NetworkChangeManage.get().unregisterService();
        }
    }

    private static class OnFlyOnAnimBuild implements AnimationPool.OnAnimationBuilder {
        @NonNull
        @Override
        public View onCreateAnimView(@NonNull Context context,
                                     @NonNull AnimationPool.AnimationHolder holder,
                                     int holderType) { return new ImageView( context ); }

        @Nullable
        @Override
        public AnimationPool.AnimationHolder onBindHolder(@NonNull AnimationPool.AnimationHolder holder,
                                                          @NonNull View animView,
                                                          @Nullable Object data,
                                                          int holderType,
                                                          @NonNull Consumer<AnimationPool.AnimationHolder> call) {
            if( data == null || !( animView instanceof ImageView ) ) return null;
            ImageView ivImg = (ImageView) animView;
            ivImg.setScaleType( ImageView.ScaleType.CENTER_INSIDE );
            ivImg.setBackgroundColor( Color.BLACK );
            ivImg.setImageResource( ObjUtils.parseInt( data ) );
            return holder;
        }

        @AlignType
        @Override
        public int onEnableFromAlign(int holderType) { return AlignType.DEFAULT; }

        @AlignType
        @Override
        public int onEnableToAlign(int holderType) { return AlignType.DEFAULT; }

        @Override
        public void onAnimViewLayoutParams(@NonNull AnimationPool.AnimationHolder holder,
                                           @NonNull ViewGroup.LayoutParams lp,
                                           int holderType) {
            View fromView = holder.getFromView();
            if( fromView == null ) return;
            lp.width = fromView.getWidth();
            lp.height = fromView.getHeight();
        }
    }

    @Override
    public void onBackPressed() {
        StackManage.get().doubleBackPressedExit(this, (Function<Boolean, Boolean>) input -> {
            if( input ) super.onBackPressed();
            return true;
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
//        NetworkChangeManage.get().unregisterService();

        //释放心跳
        LiveTime.get().releaseLiveTime();
//        //或者
//        LiveTime.get().releaseLiveTime(
//                HandlerManage.create(),
//                TestApplication.LIVE_TIME_ID_TEXT_1_SECOND,
//                TestApplication.LIVE_TIME_ID_TEXT_5_SECOND
//        );
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        DialogPermission.get().onActivityResult( this, requestCode, resultCode, data );
    }
}
